import { DataResponse, PageInfo } from '../services/core';
import { AxiosResponse } from 'axios';
import { AxiosResponseHeaders } from 'axios';

export const HttpUtil = {
  getCode: <T>(response: DataResponse<T>): number => response.data.code,

  getMessage: <T>(response: DataResponse<T>): string => response.data.msg,

  getData: <T>(response: DataResponse<T>): T => response.data.data,

  setData: <T, S>(response: DataResponse<T>, data: S): DataResponse<S> => {
    response.data.data = data as never;
    return response as unknown as DataResponse<S>;
  },

  getList: <T>(response: DataResponse<PageInfo<T>>): T[] => response.data.data.records,

  setList: <T, S>(response: DataResponse<PageInfo<T>>, records: S[]): DataResponse<PageInfo<S>> => {
    response.data.data.records = records as never;
    return response as unknown as DataResponse<PageInfo<S>>;
  },

  getPageInfo: <T>(response: DataResponse<PageInfo<T>>): PageInfo<T> => response.data.data,

  getHeaders: <T>(response: DataResponse<T>): AxiosResponseHeaders => response.headers,

  getHeader: <T>(response: DataResponse<T>, headerName: string): string | undefined =>
    response.headers[headerName.toLowerCase()],

  getToken: <T>(response: DataResponse<T>): string | undefined => response.headers['token'],

  isOk: <T>(response: AxiosResponse<T>): boolean => response.status === 200,

  isCreated: <T>(response: AxiosResponse<T>): boolean => response.status === 201,

  isNoContent: <T>(response: AxiosResponse<T>): boolean => response.status === 204,

  is2xx: <T>(response: AxiosResponse<T>): boolean => response.status >= 200 && response.status < 300,

  isBadRequest: <T>(response: AxiosResponse<T>): boolean => response.status === 400,

  isUnauthorized: <T>(response: AxiosResponse<T>): boolean => response.status === 401,

  isForbidden: <T>(response: AxiosResponse<T>): boolean => response.status === 403,

  isNotFound: <T>(response: AxiosResponse<T>): boolean => response.status === 404,

  is4xx: <T>(response: AxiosResponse<T>): boolean => response.status >= 400 && response.status < 500,

  is5xx: <T>(response: AxiosResponse<T>): boolean => response.status >= 500 && response.status < 600,

  post: (url: string, params?: { [key: string]: string }): void => {
    const formElement = document.createElement('form');
    formElement.action = url;
    formElement.target = '_self';
    formElement.method = 'post';
    formElement.style.display = 'none';
    if (params) {
      Object.keys(params).forEach(value => {
        const opt = document.createElement('textarea');
        opt.name = value;
        opt.value = params[value];
        formElement.appendChild(opt);
      });
    }
    document.body.appendChild(formElement);
    formElement.submit();
    document.body.removeChild(formElement);
  },

  getParams: (url: string): { [key: string]: unknown } => {
    const param: { [key: string]: unknown } = {};
    url.replace(/([^?&]+)=([^?&]+)/g, function (s, v: string, k) {
      const val = decodeURIComponent(k);
      const num = Number(val);
      if (isNaN(num)) {
        if (val === 'true') {
          param[v] = true;
        } else if (val === 'false') {
          param[v] = false;
        } else {
          param[v] = val;
        }
      } else {
        param[v] = num;
      }
      return k + '=' + v;
    });
    return param;
  },

  redirect: (redirect: string): void => {
    window.location.href = redirect;
  },

  reload: (): void => {
    window.location.reload();
  },

  isExternal: (path: string): boolean => {
    return /^(http:|https:|mailto:|tel:)/.test(path);
  },
};
